deferred_construction.hpp
namespace type_safe
{
template <typename T>
class deferred_construction;
}
type_safe::deferred_construction
template <typename T>
class deferred_construction
{
public:
using value_type = T;
deferred_construction() noexcept;
deferred_construction(const deferred_construction& other);
deferred_construction(deferred_construction&& other) noexcept('hidden');
deferred_construction(value_type) = delete;
~deferred_construction() noexcept;
deferred_construction& operator=(deferred_construction) = delete;
template <typename U>
deferred_construction& operator=(U&& u);
//=== Modifiers ===//
template <typename ... Args>
void emplace(Args&&... args);
//=== Observers ===//
bool has_value() const noexcept;
operator bool() const noexcept;
value_type& value() & noexcept;
const value_type& value() const & noexcept;
value_type&& value() && noexcept;
const value_type&& value() const && noexcept;
};
A tiny wrapper to create an object without constructing it yet.
This is useful if you have a type that is default constructible, but can't be initialized properly - yet. It works especially well with ts::output_parameter.
It has two states: Either it is initialized in which case you can get its value, or it is un-initialized in which case you cannot get its value. All objects start out un-initialized. For consistency with ts::basic_optional it provides a similar interface, yet it is not as flexible and does not allow to reset it to the uninitialized state, once initialized.
type_safe::deferred_construction::deferred_construction
deferred_construction() noexcept;
Default constructor.
Effects: Creates it in the un-initialized state.
type_safe::deferred_construction::deferred_construction
deferred_construction(const deferred_construction& other);
Copy constructor:
Effects: If other
is un-initialized, it will be un-initialized as well. If other
is initialized, it will copy the stored value.
Throws: Anything thrown by the copy constructor of value_type
if other
is initialized.
type_safe::deferred_construction::deferred_construction
deferred_construction(deferred_construction&& other) noexcept('hidden');
Move constructor:
Effects: If other
is un-initialized, it will be un-initialized as well. If other
is initialized, it will copy the stored value.
Throws: Anything thrown by the move constructor of value_type
if other
is initialized.
Notes: other
will still be initialized after the move operation, it is just in a moved-from state.
type_safe::deferred_construction::deferred_construction
deferred_construction(value_type) = delete;
Notes: You cannot construct it from the type directly. If you are able to do that, there is no need to use defer_construction
!
type_safe::deferred_construction::~deferred_construction
~deferred_construction() noexcept;
Effects: If it is initialized, it will destroy the value. Otherwise it has no effect.
type_safe::deferred_construction::operator=
deferred_construction& operator=(deferred_construction) = delete;
Notes: You cannot copy or move assign it. This is a deliberate design decision to guarantee, that an initialized object stays initialized, no matter what.
type_safe::deferred_construction::operator=
template <typename U>
deferred_construction& operator=(U&& u);
Effects: Same as emplace(std::forward<U>(u))
.
Requires: value_type
must be constructible from U
.
Notes: You must not use this function to actually "assign" the value, like emplace()
, the object must not be initialized.
type_safe::deferred_construction::emplace
template <typename ... Args>
void emplace(Args&&... args);
Effects: Initializes the object with the value_type
constructed from args
.
Requires: has_value() == false
.
Throws: Anything thrown by the chosen constructor of value_type
.
Notes: You must only call this function once, after the object has been initialized, you can use value()
to assign to it.
type_safe::deferred_construction::has_value
bool has_value() const noexcept;
Returns: true
if the object is initialized, false
otherwise.
type_safe::deferred_construction::operator bool
operator bool() const noexcept;
Returns: The same as has_value()
.
type_safe::deferred_construction::value
(1) value_type& value() & noexcept;
(2) const value_type& value() const & noexcept;
(3) value_type&& value() && noexcept;
(4) const value_type&& value() const && noexcept;
Access the stored value.
Returns: A (const
) (rvalue) reference to the stored value.
Requires: has_value() == true
.